package digital_cash_system;

import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Date;

public class PublishedHash
{
	final static String hashingAlgorithm = "SHA-512";
	
	/**
	 * Collision free hash function
	 * 
	 * @param ga
	 *            - a member of G(q)
	 * @param gb
	 *            - a member of G(q)
	 * @param gc
	 *            - a member of G(q)
	 * @param gd
	 *            - a member of G(q)
	 * @param ge
	 *            - a member of G(q)
	 * @return k - a member of the set Z(q)* = {1, 2, ..., q-1}
	 */
	public static BigInteger hashH(BigInteger ga, BigInteger gb, BigInteger gc,
			BigInteger gd, BigInteger ge, BigInteger q)
	{
		String concatG = ga.toString() + gb.toString() + gc.toString()
				+ gd.toString() + ge.toString();

		return hash(concatG, q);
	}

	/**
	 * Collision free hash function
	 * 
	 * @param gf
	 *            - a member of G(q)
	 * @param gg
	 *            - a member of G(q)
	 * @param shopId
	 * @param dateTime
	 * @return k' - a member of the set Z(q)* = {1, 2, ..., q-1}
	 */
	public static BigInteger hashH0(BigInteger gf, BigInteger gg, int shopId,
			Date dateTime, BigInteger q)
	{
		
		String concat = gf.toString() + gg.toString() + String.valueOf(shopId)
				+ dateTime.getTime();

		return hash(concat, q);
	}

	private static BigInteger hash(String concat, BigInteger q)
	{
		MessageDigest messageDigest = null;
		try
		{
			messageDigest = MessageDigest.getInstance(hashingAlgorithm);
		} catch (NoSuchAlgorithmException e)
		{
			e.printStackTrace();
		}

		messageDigest.reset();
		messageDigest.update(concat.getBytes());
		byte messageDigestResult[] = messageDigest.digest();

		BigInteger result;
		SecureRandom secureRandom = new SecureRandom(messageDigestResult);
		do
		{
			result = new BigInteger(q.bitLength(), secureRandom);
		} while (result.compareTo(q.subtract(BigInteger.ONE)) == 1
				|| result.equals(BigInteger.ZERO));

		return result;
	}
}
